import {
  AfterViewInit,
  Directive,
  ElementRef,
  Input,
  OnChanges,
  OnInit,
  Renderer2,
  SimpleChanges,
} from '@angular/core';
import { Platform } from '@angular/cdk/platform';
import { MediaMatcher } from '@angular/cdk/layout';
import { ReplaySubject } from 'rxjs';
import { TypeUtils } from '../core/utils/type';
import { gridResponsiveConfig, LvAlign, LvGutterObject, LvJustify } from './interface';

@Directive({
  selector: '[lv-row], lv-row, [lvRow]',
  exportAs: 'lvRow',
  host: {
    class: 'lv-row',
    '[class.lv-row-align-start]': "lvAlign === 'start'",
    '[class.lv-row-align-center]': "lvAlign === 'center'",
    '[class.lv-row-align-end]': "lvAlign === 'end'",
    '[class.lv-row-start]': "lvJustify === 'start'",
    '[class.lv-row-center]': "lvJustify === 'center'",
    '[class.lv-row-end]': "lvJustify === 'end'",
    '[class.lv-row-space-around]': "lvJustify === 'space-around'",
    '[class.lv-row-space-between]': "lvJustify === 'space-between'",
    '[class.lv-row-space-evenly]': "lvJustify === 'space-evenly'",
  },
})
export class RowDirective implements OnInit, OnChanges, AfterViewInit {
  @Input() lvAlign: LvAlign;
  @Input() lvJustify: LvJustify;
  @Input() lvGutter: number | LvGutterObject | [number, number] | [LvGutterObject, LvGutterObject];

  reallyGutter$ = new ReplaySubject<[number | null, number | null]>(1); // NEED_DO

  private typeUtil = TypeUtils;

  constructor(
    public elementRef: ElementRef,
    public renderer: Renderer2,
    public platform: Platform,
    public mediaMatcher: MediaMatcher,
  ) {}

  ngOnInit(): void {
    this.setGutterStyle();
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.lvGutter) {
      this.setGutterStyle();
    }
  }

  ngAfterViewInit(): void {
    const { isBrowser } = this.platform;

    if (isBrowser) {
      // NEED_DO 视窗变更，改变样式
    }
  }

  renderGutter(styleName: string, gutter: number | null): void {
    const element = this.elementRef.nativeElement;

    if (gutter) {
      this.renderer.setStyle(element, styleName, `-${gutter / 2}px`);
    }
  }

  setGutterStyle(): void {
    const [horizontalGutter, verticalGutter] = this.getGutter();
    this.reallyGutter$.next([horizontalGutter, verticalGutter]);

    this.renderGutter('margin-left', horizontalGutter);
    this.renderGutter('margin-right', horizontalGutter);
    this.renderGutter('margin-top', verticalGutter);
    this.renderGutter('margin-bottom', verticalGutter);
  }

  getGutter(): [number | null, number | null] {
    const gutter: [number | null, number | null] = [null, null];
    const cacheGutters = this.lvGutter || 0;
    const formattedGutters = Array.isArray(cacheGutters) ? cacheGutters : [cacheGutters, null];

    formattedGutters.forEach((item, index): void => {
      if (this.typeUtil.isObject(item) && this.typeUtil.isNotNil(item)) {
        gutter[index] = null;

        Object.keys(gridResponsiveConfig).forEach((breakpoint): void => {
          if (this.mediaMatcher.matchMedia(gridResponsiveConfig[breakpoint]).matches && item[breakpoint]) {
            gutter[index] = item[breakpoint];
          }
        });
      } else {
        gutter[index] = Number(item) || null;
      }
    });

    return gutter;
  }
}
